#ifndef __UTILS_STUFF
#define __UTILS_STUFF

/*
 *   This file is part of ed_pvr.
 *
 *   ed_pvr is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   ed_pvr is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with ed_pvr.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef __cplusplus
    extern "C" {
#endif

#include <pthread.h>
#include <stdarg.h>
#include <stdint.h>
#include <inttypes.h>
#ifdef USE_GLIB
#include <glib.h>
#endif

#define OUTPUT_FILE_MODE		0666
#define BYTE_SIZE				8


#define	UTILS_MAX_LOG_LEN		4096
#define MAX_33BITS				0x1FFFFFFFF

#define SLEEP_250MS				usleep(250000);
#define SLEEP_100MS				usleep(100000);
#define SLEEP_50MS				usleep(50000);
#define SLEEP_1MS				usleep(1000);

#define MAX_FILENAME_SIZE		(4096*2)
#define FILE_INPUT_READ_MIN		1000000
#define FILE_INPUT_STDIN		"stdin"
#define FILE_INPUT_STDIN_FD		0

#define FILE_OUTPUT_STDOUT		"stdout"
#define FILE_OUTPUT_STDOUT_FD		1

#ifndef MIN
#define MIN(a,b) ( (a)<(b) ? (a) : (b) )
#endif

#ifndef MAX
#define MAX(a,b) ( (a)>(b) ? (a) : (b) )
#endif

struct utils_datapair_struct
{
	uint8_t throw_away;
	uint8_t * data;
	uint32_t data_size;
	struct utils_datapair_struct *next;
};
typedef struct utils_datapair_struct UTILS_DATAPAIR_STRUCT;

struct utils_hostport_struct
{
	char hostname[4096];
	uint16_t port;
//	void * extra;
};
typedef struct utils_hostport_struct UTILS_HOSTPORT_STRUCT;

struct utils_log_struct
{
#ifdef USE_GLIB
	GAsyncQueue *queue;
#endif
//	g_async_queue_new
//	UTILS_LINKEDLIST_STRUCT *log;
	pthread_mutex_t log_lock;
};
typedef struct utils_log_struct UTILS_LOG_STRUCT;




/*
struct utils_curl_fetch_options
{
//	CURL *handle;
	void *handle;
	char *errbuf;
	char *user_agent;
	uint8_t proxy_type;
	char *proxy;
	int connect_timeout;
	int timeout;
	int buffer_size;
	int dns_cache_timeout;
	int fail_on_error;
};
typedef struct utils_curl_fetch_options UTILS_CURL_FETCH_OPTIONS;
*/

// --------------------------
struct textfile_in_memory
{
    uint32_t pos;
    uint32_t line_count;
    uint32_t data_size;
    uint8_t *data;
};
typedef struct textfile_in_memory TEXTFILE_IN_MEMORY;

struct textfile_memline
{
	uint32_t line_num;
	char *line_data;
};
typedef struct textfile_memline TEXTFILE_MEMLINE;

// Function declarations
// **************************************
TEXTFILE_IN_MEMORY * memfile_init(char *, int);
char * memfile_getnext_line(TEXTFILE_IN_MEMORY *, int);
int memfile_getline_count(TEXTFILE_IN_MEMORY *);


int8_t file_exists(char *);
off_t get_file_size(char *);
//int write_bytes_to_socket(int, uint8_t *, int, long int, long int);
//int get_bytes_from_socket(int, uint8_t *, int, long int, long int, uint32_t);
ssize_t write_bytes_to_socket(int, uint8_t *, int, uint64_t, int*);
ssize_t get_bytes_from_socket(int, uint8_t *, int, uint64_t, int*);
ssize_t get_bytes_from_socket2(int, uint8_t *, int, uint64_t, int*);
int get_bytes_from_file(int, uint8_t *, int);
ssize_t get_string_from_socket(int, uint8_t *, int);


int poll_wait_read(int, int, int);
int poll_wait_write(int, int, int);

int select_wait_read(int, int, int);
int select_wait_write(int, int, int);
int get_listen_socket(char *, uint16_t);
int doconnect(char *, uint16_t, int);
//int doconnect2(char *, uint16_t);
size_t generic_curl_handler(void *, size_t, size_t, void *);
unsigned int htoi (const char *);

unsigned int str_hash(char *);

char *get_local_time(void);
char *get_local_date(void);
uint32_t crc32(uint8_t *, uint32_t);
size_t get_bufsize(int);
uint32_t get_nearest_page_size(uint32_t, uint32_t);
uint64_t get_time_ms(void);
int utils_free_datapair(UTILS_DATAPAIR_STRUCT *);
UTILS_HOSTPORT_STRUCT * utils_split_host(char *);
//uint64_t str_to_epoch(char *);

/*
int32_t utils_ll_get_count(UTILS_LINKEDLIST_STRUCT *);
UTILS_DATAPAIR_STRUCT *utils_ll_get_first(UTILS_LINKEDLIST_STRUCT *);
UTILS_DATAPAIR_STRUCT *utils_ll_get_next(UTILS_DATAPAIR_STRUCT *);
UTILS_LINKEDLIST_STRUCT * utils_ll_init(void);
int utils_ll_del(UTILS_LINKEDLIST_STRUCT *, UTILS_DATAPAIR_STRUCT *);
UTILS_DATAPAIR_STRUCT *utils_ll_add(UTILS_LINKEDLIST_STRUCT *, void *, uint32_t);
int utils_ll_uninit(UTILS_LINKEDLIST_STRUCT *);
*/

UTILS_LOG_STRUCT *utils_log_init(void);
char * utils_log_getmsg(UTILS_LOG_STRUCT *);
void utils_log_print(UTILS_LOG_STRUCT *, const char *, ...);
void utils_log_vprint(UTILS_LOG_STRUCT *, const char *, va_list);

int utils_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *, int);

uint64_t utils_str_to_epoch2(char *, uint8_t);
uint64_t utils_str_to_epoch(char *);
char * utils_epoch_to_str(int64_t);
uint64_t utils_date_to_epoch(char *);
char *utils_split_value_after(char *, char);

int b64decode(char *);

int str_to_bytes(char *, unsigned char *, int);
char *url_encode(char *);

#ifdef __cplusplus
    }
#endif

#endif

